home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- * *
- * Preliminary *
- * Amiga AppShell (tm) *
- * *
- * Copyright (c) 1990,1991 Commodore-Amiga, Inc. All Rights Reserved. *
- * *
- * This software and information is proprietary, preliminary, and *
- * subject to change without notice. *
- * *
- * DISCLAIMER *
- * *
- * THIS SOFTWARE IS PROVIDED "AS IS". *
- * NO REPRESENTATIONS OR WARRANTIES ARE MADE WITH RESPECT TO THE *
- * ACCURACY, RELIABILITY, PERFORMANCE, CURRENTNESS, OR OPERATION *
- * OF THIS SOFTWARE, AND ALL USE IS AT YOUR OWN RISK. *
- * NEITHER COMMODORE NOR THE AUTHORS ASSUME ANY RESPONSIBILITY OR *
- * LIABILITY WHATSOEVER WITH RESPECT TO YOUR USE OF THIS SOFTWARE. *
- * *
- * Non-Disclosure *
- * *
- * This information is not to be disclosed to any other company, *
- * individual or party. Discussion is to be restricted to CBM *
- * approved discussion areas, such as the closed conferences on bix; *
- * amiga.cert, amiga.com, amiga.beta/appshell. *
- * *
- ************************************************************************
- */
-
- #include "multiproj.h"
-
- #define DI(x) ;
-
- void kprintf (void *, ...);
-
- /* Project function table */
- struct Funcs PTable[] =
- {
- /* Function with an argument template */
- {"New", PNewFunc, NewID,},
- {"Open", POpenFunc, OpenID, "FILENAME,FORCE/S", 2L, },
- {"Save", PSaveFunc, SaveID, ",", 0L, },
- {"SaveAs",PSaveAsFunc, SaveAsID, "NAME", 1L, },
- {"About",PAboutFunc, AboutID, },
- {"Quit", PQuitFunc, QuitID, "FORCE/S,ALL/S", 2L, },
- {"Change", ChangeFunc, ChangeID, },
-
- /* These function can not be accessed by the user */
- {"PInit", PInitFunc, PInitID, NULL, NULL, APSHF_PRIVATE},
- {"OpenMain", OpenMainFunc, OpenMainID, NULL, NULL, APSHF_PRIVATE},
- {"OpenAbout", OpenAboutFunc, OpenAboutID, NULL, NULL, APSHF_PRIVATE},
- {"DropIcon", DropIconFunc, DropIconID, NULL, NULL, APSHF_PRIVATE,},
- {"PExit", PExitFunc, PExitID, NULL, NULL, APSHF_PRIVATE},
-
- /* Marks the end of the array */
- {NULL, NO_FUNCTION,}
- };
-
- /* All text used in the application must be defined in a text array. Then
- * referred to by numeric ID. */
- STRPTR Def_Text[] =
- {
- /* Padding */
- "",
- "Loading...",
-
- /* Main window menus */
- " TITLE PROJECT LABEL Project",
- " ITEM NEW LABEL New KEY N CMD New",
- " ITEM OPEN LABEL \"Open...\" KEY O CMD Open",
- " BAR",
- " ITEM SAVE LABEL Save KEY S CMD Save",
- " ITEM SAVEAS LABEL \"Save As...\" KEY A CMD SaveAs",
- " BAR",
- " ITEM CLOSE LABEL Close CMD Quit",
- " BAR",
- " ITEM ABOUT LABEL \"About...\" CMD About",
- " BAR",
- " ITEM QUIT LABEL \"Quit MultiProj\" KEY Q CMD \"Quit All\"",
-
- " TITLE EXTRAS LABEL Extras",
- " ITEM CHANGE LABEL \"Change Project\" KEY / CMD Change",
- " ITEM CMDSHELL LABEL \"Command Shell...\" KEY . CMD CmdShell",
- " END",
-
- "Aborted by user",
- #define PERR_USER_ABORT 18
-
- "No name provided",
- #define PERR_NO_NAME 19
-
- "Couldn't load %s",
- #define PERR_CANT_LOAD 20
-
- "Requires project",
- #define PERR_NO_PROJECT 21
-
- "Couldn't create %s",
- #define PERR_CANT_CREATE 22
-
- "Couldn't write to %s",
- #define PERR_CANT_WRITE 23
-
- /* NULL termination is required */
- NULL
- };
-
- /* The following tag array consists of GadTool tags for Window Environment
- * objects. */
- struct TagItem td_tags[] =
- {
- {APSH_GTFlags, PLACETEXT_IN},
- {TAG_DONE,},
- };
-
- /* These are the objects that are going to be within our main window.
- * Note that the window itself is an object, and receives the SAME name
- * as in the WindowEnvironment tag list, APSH_NameTag. If you want
- * to specify any window tags, attach them to the window object. */
- struct Object objects[] =
- {
- {&objects[1], 0, 0, OBJ_Window, NULL, NULL, NULL, "Main", 1L,
- {0, 0, 320, 0}, },
-
- {NULL, 0, 0, OBJ_Text, NULL, NULL, NULL, "Name", 0L,
- {8, 4, 350, 10}, td_tags, },
- };
-
- /* This is a Window Environment tag list. It describes a window. */
- struct TagItem mainenv[] =
- {
- {APSH_NameTag, (ULONG) "Main"},
- {APSH_Objects, (ULONG) objects},
- {APSH_TTMenu, 2L},
- {APSH_WinAOpen, OpenMainID},
- {APSH_RefreshData, OpenMainID},
- {TAG_DONE,}
- };
-
- /* Command Shell user interface environment specification array */
- struct TagItem Handle_DOS[] =
- {
- /* Presence of this tag, makes the Command Shell to stay closed until
- * the user sends a CMDSHELL OPEN command. */
- {APSH_Status, APSHP_INACTIVE},
- {APSH_Rating, APSH_REQUIRED},
- {TAG_DONE,}
- };
-
- /* These tags describe the Intuition user interface. */
- struct TagItem Handle_IDCMP[] =
- {
- {APSH_Rating, APSH_REQUIRED},
- {TAG_DONE,}
- };
-
- /* ARexx user interface environment specification array */
- static struct TagItem Handle_AREXX[] =
- {
- {APSH_Extens, (ULONG) "skel"},
- {APSH_Rating, APSH_OPTIONAL},
- {TAG_DONE,}
- };
-
- /* These tags describe the Simple IPC user interface. */
- static struct TagItem Handle_SIPC[] =
- {
- {APSH_Rating, APSH_REQUIRED},
- {TAG_DONE,}
- };
-
- struct TagItem appwinenv[] =
- {
- {APSH_NameTag, (ULONG) "MAIN"}, /* Window to make into AppWindow */
- {APSH_AppDDrop, DropIconID}, /* function after drop */
- {APSH_CmdFlags, APSH_WBF_NOLIST}, /* Don't add the icons to any list */
- {TAG_DONE,}
- };
-
- /* These tags describe the Workbench user interface. */
- struct TagItem Handle_WB[] =
- {
- {APSH_AppWindowEnv, (ULONG) appwinenv},
- {APSH_Rating, APSH_OPTIONAL},
- {TAG_DONE,}
- };
-
- /* Application Environment:
- * Tell about our slave project application */
- struct TagItem Project_App[] =
- {
- /* About the application */
- {APSH_AppName, (ULONG) APPNAME},
- {APSH_AppVersion, (ULONG) APPVERS},
- {APSH_AppCopyright, (ULONG) APPCOPY},
- {APSH_AppAuthor, (ULONG) APPAUTH},
-
- /* Specify the application function table */
- {APSH_FuncTable, (ULONG) PTable},
-
- /* Specify the application text table */
- {APSH_DefText, (ULONG) Def_Text},
-
- /* Tell how memory we need for our own data */
- {APSH_UserDataSize, sizeof (struct AppData)},
-
- /* Must always specify the SIPC user interface */
- {APSH_AddSIPC_UI, (ULONG) Handle_SIPC},
-
- /* Add an ARexx user interface */
- {APSH_AddARexx_UI, (ULONG) Handle_AREXX},
-
- /* Add a Command Shell user interface */
- {APSH_AddCmdShell_UI, (ULONG) Handle_DOS},
-
- /* Add an Intuition user interface */
- {APSH_AddIntui_UI, (ULONG) Handle_IDCMP},
-
- /* Add a Workbench user interface */
- {APSH_AddWB_UI, (ULONG) Handle_WB},
-
- /* Specify a custom initialization routine */
- {APSH_AppInit, PInitID},
- {APSH_AppExit, PExitID},
-
- {TAG_DONE,}
- };
-
- /* local functions */
- LONG save_project (struct AppInfo *ai, STRPTR name);
- LONG load_project (struct AppInfo *ai, STRPTR name);
- SHORT myEasyRequest (struct Window *, UBYTE *, ULONG *, UBYTE *, UBYTE *, int, ...);
- BOOL CheckForChanges (struct AppInfo * ai, struct ProjNode * pn);
- LONG FixFileAndPath (struct FileRequester *rf, STRPTR name);
-
- /* Sample initialization function */
- VOID PInitFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- struct Project *p = &(ai->ai_Project);
- struct TagItem *attrs = af->af_Attrs;
- extern struct TagItem mainenv[];
- struct ProjNode *pn;
- WORD i;
-
- /* Get a pointer to our project node */
- DI (kprintf ("PInitFunc enter\n"));
- if (pn = (struct ProjNode *) GetTagData (APSH_ProjInfo, NULL, attrs))
- {
- /* Remember the project node */
- p->p_CurProj = ad->ad_PN = pn;
-
- /* Get a pointer to our Master's AppInfo */
- ad->ad_MAI = (struct AppInfo *) GetTagData (APSH_AppHandle, NULL, attrs);
-
- /* Allocate the file requesters */
- for (i = 0; i < FR_MAX; i++)
- {
- ad->ad_FR[i] = AllocAslRequest (ASL_FileRequest, NULL);
- }
-
- /* Unset the file requester positioning */
- ad->ad_Width = (-1);
-
- /* Initialize the file requester */
- FixFileAndPath (ad->ad_FR[FR_PROJ], pn->pn_ProjPath);
-
- /* Open the Main window */
- DI (kprintf ("Open Main window\n"));
- HandlerFunc (ai,
- APSH_Handler, "IDCMP",
- APSH_Command, APSH_MH_OPEN,
- APSH_WindowEnv, (ULONG) mainenv,
- TAG_DONE);
- }
- else
- {
- /* We require a project node */
- ai->ai_Pri_Ret = RETURN_ERROR;
- ai->ai_Sec_Ret = PERR_NO_PROJECT;
- ai->ai_TextRtn =
- PrepText (ai, APSH_USER_ID, ai->ai_Sec_Ret, NULL);
- }
- DI (kprintf ("PInitFunc exit\n"));
- }
-
- /* This function gets called after the main event processing loop exits,
- * and before deallocating all the user interfaces. It is specified by the
- * APSH_AppExit tag in the Application Description tag array. Note that the
- * AppData structure which has been allocated for us, is deallocated by
- * AppShell after freeing the user interfaces. */
-
- VOID
- PExitFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- WORD i;
-
- if (ad)
- {
- /* Free the file requesters */
- for (i = 0; i < FR_MAX; i++)
- {
- /* Do we have a file requester? */
- if (ad->ad_FR[i])
- {
- /* Free the file requester */
- FreeFileRequest (ad->ad_FR[i]);
- ad->ad_FR[i] = NULL;
- }
- }
- }
- }
-
- /* This function is called every time the Main window is opened. It
- * was specified by using the APSH_WinAOpen tag in the Main Window
- * Environemt tag array. I'm also 'cheating' and calling it everytime
- * I want to refresh the window and graphics. */
-
- VOID OpenMainFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- struct Window *win;
- struct Gadget *gad;
-
- /* Update the mode gadget */
- if (APSHGetGadgetInfo (ai, "Main", "Name", (ULONG *) & win, (ULONG *) & gad))
- {
- /* Update the string gadget */
- GT_SetGadgetAttrs (gad, win, NULL,
- GTTX_Text, ad->ad_PN->pn_ProjPath,
- TAG_DONE);
- }
-
- /* Set the window title */
- sprintf (ad->ad_Tmp, "window title \"%s\"", ad->ad_PN->pn_Name);
- PerfFunc (ai, NULL, ad->ad_Tmp, NULL);
- }
-
- /* Create a new project work area */
- VOID PNewFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- struct MsgHandler *mh;
-
- /* Make sure we have a master */
- if (ad->ad_MAI)
- {
- /* See if they have a SIPC port */
- if (mh = HandlerData (ad->ad_MAI, APSH_Handler, "SIPC", TAG_DONE))
- {
- /* Tell our master to open a new application */
- HandlerFunc (ai,
- APSH_Handler, "SIPC",
- APSH_Command, AH_SENDCMD,
- APSH_NameTag, mh->mh_PortName,
- APSH_CmdString, (ULONG) "New",
- TAG_DONE);
- }
- }
- }
-
- /* Open a project into the existing work area */
- VOID POpenFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- struct FileRequester *fr = ad->ad_FR[FR_PROJ];
- struct TagItem *attrs = af->af_Attrs;
- struct Funcs *f;
- STRPTR name = NULL;
- BOOL cancel = FALSE;
- BOOL force = FALSE;
-
- /* set the wait pointer */
- APSHSetWaitPointer (ai, NULL);
-
- /* See if we have a parsed command */
- if (f = af->af_FE)
- {
- /* See if they passed a file name */
- name = (STRPTR) f->fe_Options[0];
-
- /* Did they set the force switch? */
- force = (BOOL) f->fe_Options[1];
- }
- else
- {
- /* See if they passed a name with a tag */
- name = (STRPTR) GetTagData (APSH_NameTag, NULL, attrs);
- }
-
- /* Is there an existing project? */
- if (!force)
- {
- BOOL cancel = FALSE;
-
- /* Prompt user */
- if (cancel = CheckForChanges (ai, ad->ad_PN))
- {
- return;
- }
- }
-
- /* Do we need to prompt for a name? */
- if (!(name))
- {
- /* Do we have a file requester? */
- if (fr)
- {
- struct TagItem tg[10];
- struct Window *win = NULL;
-
- /* Get the window pointer */
- APSHGetWindowInfo (ai, "Main", (ULONG *) & win);
-
- /* Initialize the file requester position */
- if (ad->ad_Width == (-1))
- {
- ad->ad_LeftEdge = (win) ? (win->BorderLeft + 1) : 0;
- ad->ad_TopEdge = (win) ? win->BorderTop : 0;
- ad->ad_Width = 320;
- ad->ad_Height = MAX (((win) ? (win->Height - (win->BorderTop + win->BorderBottom)) : 150), 140);
- }
-
- /* Set the file requester position */
- tg[4].ti_Tag = ASL_LeftEdge;
- tg[4].ti_Data = (ULONG) (win) ? (win->LeftEdge + ad->ad_LeftEdge) : ad->ad_LeftEdge;
- tg[5].ti_Tag = ASL_TopEdge;
- tg[5].ti_Data = (ULONG) (win) ? (win->TopEdge + ad->ad_TopEdge) : ad->ad_TopEdge;
- tg[6].ti_Tag = ASL_Width;
- tg[6].ti_Data = (ULONG) ad->ad_Width;
- tg[7].ti_Tag = ASL_Height;
- tg[7].ti_Data = (ULONG) ad->ad_Height;
-
- tg[0].ti_Tag = ASL_Hail;
- tg[0].ti_Data = (ULONG) "Select File to Open";
- tg[1].ti_Tag = ASL_FuncFlags;
- tg[1].ti_Data = NULL;
- tg[2].ti_Tag = ASL_OKText;
- tg[2].ti_Data = (ULONG) "Open";
- tg[3].ti_Tag = ASL_Window;
- tg[3].ti_Data = (ULONG) win;
- tg[8].ti_Tag = ASL_Pattern;
- tg[8].ti_Data = (ULONG) "~(#?.info)";
- tg[9].ti_Tag = TAG_DONE;
-
- /* Request the name */
- if (AslRequest (fr, tg))
- {
- /* Fix the entries */
- FixFileAndPath (fr, NULL);
- strcpy (ad->ad_Name, fr->rf_Dir);
- AddPart (ad->ad_Name, fr->rf_File, 510);
-
- /* See if a name was entered */
- if (FixFileAndPath (fr, ad->ad_Name))
- {
- name = ad->ad_Name;
- }
- }
- else
- {
- /* User aborted requester */
- ai->ai_Pri_Ret = RETURN_WARN;
- ai->ai_Sec_Ret = PERR_USER_ABORT;
- ai->ai_TextRtn =
- PrepText (ai, APSH_USER_ID, PERR_USER_ABORT, NULL);
-
- /* Canceled */
- cancel = TRUE;
- }
-
- /* Remember where they moved it */
- ad->ad_LeftEdge = fr->rf_LeftEdge - ((win) ? win->LeftEdge : 0);
- ad->ad_TopEdge = fr->rf_TopEdge - ((win) ? win->TopEdge : 0);
- ad->ad_Width = fr->rf_Width;
- ad->ad_Height = fr->rf_Height;
- }
- }
-
- /* Do we have a file name */
- if (!cancel && name)
- {
- /* LOAD THE PROJECT HERE */
- if (load_project (ai, name))
- {
- UBYTE node[128];
- BPTR lock;
-
- /* Parse the name */
- stcgfp (ad->ad_Tmp, name);
- stcgfn (node, name);
-
- /* Get a lock on the directory */
- if (lock = Lock (ad->ad_Tmp, ACCESS_READ))
- {
- struct WBArg wbarg;
-
- /* Fill in the WBArg */
- wbarg.wa_Lock = lock;
- wbarg.wa_Name = node;
-
- /* Update the project node */
- UpdateProject (ai, ad->ad_PN, &wbarg);
-
- /* Unlock our temporary lock */
- UnLock (lock);
- }
-
- /* Clear the change flag */
- ad->ad_PN->pn_Changed = FALSE;
-
- /* Refresh the display */
- OpenMainFunc (h, ai, af);
- }
- }
- else if (!cancel)
- {
- /* No name given */
- ai->ai_Pri_Ret = RETURN_ERROR;
- ai->ai_Sec_Ret = PERR_NO_NAME;
- ai->ai_TextRtn =
- PrepText (ai, APSH_USER_ID, PERR_NO_NAME, NULL);
- }
-
- /* clear the wait pointer */
- APSHClearPointer (ai, NULL);
- }
-
- /* This gets called when a Workbench icon is dropped on the main window. */
- VOID DropIconFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- struct TagItem *attrs = af->af_Attrs;
- struct WBArg *wbarg;
- BOOL cancel = FALSE;
-
- /* Has there been changes? */
- if (cancel = CheckForChanges (ai, ad->ad_PN))
- {
- return;
- }
-
- if (wbarg = (struct WBArg *) GetTagData (APSH_WBArg, NULL, attrs))
- {
- BPTR lock;
-
- /* Go to the directory represented by the icon */
- if (lock = CurrentDir (wbarg->wa_Lock))
- {
- /* Get the name of the directory */
- NameFromLock (wbarg->wa_Lock, ad->ad_Name, 510);
- AddPart (ad->ad_Name, wbarg->wa_Name, 510);
-
- /* LOAD THE PROJECT HERE */
- if (load_project (ai, ad->ad_Name))
- {
- /* Update the project node */
- UpdateProject (ai, ad->ad_PN, wbarg);
-
- /* Clear the change flag */
- ad->ad_PN->pn_Changed = FALSE;
-
- /* Refresh the display */
- OpenMainFunc (h, ai, af);
- }
-
- /* Go back home */
- CurrentDir (lock);
- }
- }
- }
-
- /* Save the current project */
- VOID PSaveFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
-
- /* Not named yet */
- if ((ad->ad_PN->pn_ProjName == NULL) ||
- (strlen (ad->ad_PN->pn_ProjName) == 0L))
- {
- PSaveAsFunc (h, ai, af);
- }
- /* Is there an existing project? */
- else
- {
- /* Save the file */
- if (save_project (ai, ad->ad_PN->pn_ProjPath))
- {
- /* Clear the change flag */
- ad->ad_PN->pn_Changed = FALSE;
- }
- }
- }
-
- /* Save the current project */
- VOID PSaveAsFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- struct FileRequester *fr = ad->ad_FR[FR_PROJ];
- struct TagItem *attrs = af->af_Attrs;
- struct Funcs *f;
- STRPTR name = NULL;
- BOOL cancel = FALSE;
-
- /* set the wait pointer */
- APSHSetWaitPointer (ai, NULL);
-
- /* See if we have a parsed command */
- if (f = af->af_FE)
- {
- /* See if they passed a file name */
- name = (STRPTR) f->fe_Options[0];
- }
- else
- {
- /* See if they passed a name with a tag */
- name = (STRPTR) GetTagData (APSH_NameTag, NULL, attrs);
- }
-
- /* Do we need to prompt for a name? */
- if (!(name))
- {
- /* Do we have a file requester? */
- if (fr)
- {
- struct TagItem tg[10];
- struct Window *win = NULL;
-
- /* Get the window pointer */
- APSHGetWindowInfo (ai, "Main", (ULONG *) & win);
-
- /* Initialize the file requester position */
- if (ad->ad_Width == (-1))
- {
- ad->ad_LeftEdge = (win) ? (win->BorderLeft + 1) : 0;
- ad->ad_TopEdge = (win) ? win->BorderTop : 0;
- ad->ad_Width = 320;
- ad->ad_Height = MAX (((win) ? (win->Height - (win->BorderTop + win->BorderBottom)) : 150), 160);
- }
-
- /* Set the file requester position */
- tg[4].ti_Tag = ASL_LeftEdge;
- tg[4].ti_Data = (ULONG) (win) ? (win->LeftEdge + ad->ad_LeftEdge) : ad->ad_LeftEdge;
- tg[5].ti_Tag = ASL_TopEdge;
- tg[5].ti_Data = (ULONG) (win) ? (win->TopEdge + ad->ad_TopEdge) : ad->ad_TopEdge;
- tg[6].ti_Tag = ASL_Width;
- tg[6].ti_Data = (ULONG) ad->ad_Width;
- tg[7].ti_Tag = ASL_Height;
- tg[7].ti_Data = (ULONG) ad->ad_Height;
-
- tg[0].ti_Tag = ASL_Hail;
- tg[0].ti_Data = (ULONG) "Select File to Save";
- tg[1].ti_Tag = ASL_FuncFlags;
- tg[1].ti_Data = (FILF_SAVE | FILF_PATGAD);
- tg[2].ti_Tag = ASL_OKText;
- tg[2].ti_Data = (ULONG) "Save";
- tg[3].ti_Tag = ASL_Window;
- tg[3].ti_Data = (ULONG) win;
- tg[8].ti_Tag = ASL_Pattern;
- tg[8].ti_Data = (ULONG) "~(#?.info)";
- tg[9].ti_Tag = TAG_DONE;
-
- /* Request the name */
- if (AslRequest (fr, tg))
- {
- /* Fix the entries */
- FixFileAndPath (fr, NULL);
- strcpy (ad->ad_Name, fr->rf_Dir);
- AddPart (ad->ad_Name, fr->rf_File, 510);
-
- /* See if a name was entered */
- if (FixFileAndPath (fr, ad->ad_Name))
- {
- name = ad->ad_Name;
- }
- }
- else
- {
- /* User aborted requester */
- ai->ai_Pri_Ret = RETURN_WARN;
- ai->ai_Sec_Ret = PERR_USER_ABORT;
- ai->ai_TextRtn =
- PrepText (ai, APSH_USER_ID, ai->ai_Sec_Ret, NULL);
-
- /* Canceled */
- cancel = TRUE;
- }
-
- /* Remember where they moved it */
- ad->ad_LeftEdge = fr->rf_LeftEdge - ((win) ? win->LeftEdge : 0);
- ad->ad_TopEdge = fr->rf_TopEdge - ((win) ? win->TopEdge : 0);
- ad->ad_Width = fr->rf_Width;
- ad->ad_Height = fr->rf_Height;
- }
- }
-
- /* Do we have a file name */
- if (!cancel && name)
- {
- /* Save the file */
- if (save_project (ai, name))
- {
- UBYTE node[128];
- BPTR lock;
-
- /* Parse the name */
- stcgfp (ad->ad_Tmp, name);
- stcgfn (node, name);
-
- /* Get a lock on the directory */
- if (lock = Lock (ad->ad_Tmp, ACCESS_READ))
- {
- struct WBArg wbarg;
-
- /* Fill in the WBArg */
- wbarg.wa_Lock = lock;
- wbarg.wa_Name = node;
-
- /* Update the project node */
- UpdateProject (ai, ad->ad_PN, &wbarg);
-
- /* Unlock our temporary lock */
- UnLock (lock);
- }
-
- /* Set the real file name */
- FixFileAndPath (fr, ad->ad_PN->pn_ProjPath);
-
- /* Clear the change flag */
- ad->ad_PN->pn_Changed = FALSE;
- }
-
- /* Refresh the display */
- OpenMainFunc (h, ai, af);
- }
- else if (!cancel)
- {
- /* No name given */
- ai->ai_Pri_Ret = RETURN_ERROR;
- ai->ai_Sec_Ret = PERR_NO_NAME;
-
- ai->ai_TextRtn =
- PrepText (ai, APSH_USER_ID, ai->ai_Sec_Ret, NULL);
- }
-
- /* clear the wait pointer */
- APSHClearPointer (ai, NULL);
- }
-
- /* Shutdown routine */
- VOID PQuitFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- struct MsgHandler *mh;
- ULONG FuncID = CloseID;
- BOOL cancel = FALSE;
- BOOL force = FALSE;
- BOOL all = FALSE;
- struct Funcs *f;
-
- /* set the wait pointer */
- APSHSetWaitPointer (ai, NULL);
-
- /* See if we have a parsed command */
- if (f = af->af_FE)
- {
- /* Did they set the force switch? */
- force = (BOOL) f->fe_Options[0];
-
- /* Close all windows? */
- if (all = (BOOL) f->fe_Options[1])
- {
- FuncID = QuitID;
- }
- }
-
- /* Is there an existing project? */
- if (!force)
- {
- /* Prompt user */
- if (cancel = CheckForChanges (ai, ad->ad_PN))
- {
- return;
- }
- }
-
- /* Make sure we have a master */
- if (ad->ad_MAI)
- {
- /* Get a handle on our master's SIPC port */
- if (mh = HandlerData (ad->ad_MAI, APSH_Handler, "SIPC", TAG_DONE))
- {
- /* Prepare our Tags */
- ad->ad_TL[0].ti_Tag = APSH_ProjInfo;
- ad->ad_TL[0].ti_Data = (ULONG) ad->ad_PN;
- ad->ad_TL[1].ti_Tag = TAG_DONE;
-
- /* Tell our master to close this project work area */
- HandlerFunc (ai,
- APSH_Handler, "SIPC",
- APSH_Command, AH_SENDCMD,
- APSH_NameTag, (ULONG) mh->mh_PortName,
- APSH_CmdID, FuncID,
- APSH_CmdData, (ULONG) ad->ad_TL,
- TAG_DONE);
- }
- }
-
- /* Tell the AppShell that we're all done now. */
- ai->ai_Done = TRUE;
-
- /* set the wait pointer */
- APSHClearPointer (ai, NULL);
- }
-
- /* Simulate a changed project */
- VOID ChangeFunc (struct Hook *h, struct AppInfo *ai, struct AppFunction *af)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
-
- /* Indicate a change */
- ad->ad_PN->pn_Changed = TRUE;
- }
-
- #define REALLY_SAVE FALSE
-
- LONG save_project (struct AppInfo *ai, STRPTR name)
- {
- LONG retval = FALSE;
-
- #if REALLY_SAVE
- BPTR fh;
-
- /* Create a new file */
- if (fh = Open (name, MODE_NEWFILE))
- {
- /* Write something to the file here */
- if (Write (fh, name, strlen (name)) >= 0)
- {
- /* Show that we couldn't write to the project */
- ai->ai_Pri_Ret = RETURN_FAIL;
- ai->ai_Sec_Ret = PERR_CANT_WRITE;
- ai->ai_TextRtn =
- PrepText (ai, APSH_USER_ID, ai->ai_Sec_Ret, (int)name);
- }
-
- /* Close the file */
- Close (fh);
-
- #else
-
- /* Make sure they gave us a name */
- if (1)
- {
-
- #endif
- /* Indicate that we were able to save the project */
- retval = TRUE;
- }
- else
- {
- /* Show that we couldn't create the project */
- ai->ai_Pri_Ret = RETURN_FAIL;
- ai->ai_Sec_Ret = PERR_CANT_CREATE;
- ai->ai_TextRtn =
- PrepText (ai, APSH_USER_ID, ai->ai_Sec_Ret, (int)name);
- }
-
- return (retval);
- }
-
- LONG load_project (struct AppInfo *ai, STRPTR name)
- {
- struct AppData *ad = (struct AppData *) ai->ai_UserData;
- struct FileRequester *fr = ad->ad_FR[FR_PROJ];
- LONG retval = FALSE;
- BPTR fh;
-
- /* Open an existing file */
- if (fh = Open (name, MODE_OLDFILE))
- {
- /* Close the file */
- Close (fh);
-
- /* Set the real file name */
- FixFileAndPath (fr, name);
-
- /* Indicate that we were able to open the project */
- retval = TRUE;
- }
- else
- {
- /* Show that we couldn't load the project */
- ai->ai_Pri_Ret = RETURN_FAIL;
- ai->ai_Sec_Ret = PERR_CANT_LOAD;
- ai->ai_TextRtn =
- PrepText (ai, APSH_USER_ID, ai->ai_Sec_Ret, (int)name);
- }
-
- return (retval);
- }
-
- /* Error handling routine */
- SHORT myEasyRequest (struct Window *win, UBYTE *title, ULONG *idcmp,
- UBYTE *fpat, UBYTE *fbuts, int arg1, ...)
- {
- struct EasyStruct myEs = {NULL};
-
- myEs.es_StructSize = sizeof (struct EasyStruct);
- myEs.es_Title = title;
- myEs.es_TextFormat = fpat;
- myEs.es_GadgetFormat = fbuts;
- return ((SHORT) (EasyRequestArgs (win, &myEs, idcmp, &arg1)));
- }
-
- BOOL CheckForChanges (struct AppInfo * ai, struct ProjNode * pn)
- {
- BOOL cancel = FALSE;
-
- if (pn->pn_Changed)
- {
- UBYTE pname[255];
- SHORT button;
-
- strcpy (pname, pn->pn_Name);
-
- if (strlen (pname) < 1)
- {
- strcpy (pname, "<UnNamed>");
- }
-
- /* Project has been changed, do you want to save first? */
- button = myEasyRequest (ai->ai_Window, ai->ai_AppName, NULL,
- "%s\nhas been changed.", "Continue|Save First|Cancel",
- (int)pname);
-
- switch (button)
- {
- case 1: /* Nope, don't save */
- break;
-
- case 2: /* Yes, please save */
- PSaveFunc (NULL, ai, NULL);
- break;
-
- case 0: /* Woops! Cancel */
- /* clear the wait pointer */
- APSHClearPointer (ai, NULL);
-
- cancel = TRUE;
- break;
- }
- }
-
- return (cancel);
- }
-
- /* Get the file requester set up properly. Returns 0 if no file node
- * present, returns > 0 if there is a file node. */
- LONG FixFileAndPath (struct FileRequester *rf, STRPTR name)
- {
- LONG count = 0L;
-
- if (rf)
- {
- if (name)
- {
- stcgfp (rf->rf_Dir, name);
- count = (LONG) stcgfn (rf->rf_File, name);
- }
- else
- {
- WORD dlen = (strlen (rf->rf_Dir) - 1);
-
- if ((dlen > 0) && (rf->rf_Dir[dlen] == '/'))
- {
- rf->rf_Dir[dlen] = 0;
- }
- }
- }
-
- return (count);
- }
-